package 中等.模拟;

/**
 * 我们把玻璃杯摆成金字塔的形状，其中 第一层 有 1 个玻璃杯，
 * 第二层 有 2 个，依次类推到第 100 层，每个玻璃杯 (250ml) 将盛有香槟。
 * 从顶层的第一个玻璃杯开始倾倒一些香槟，当顶层的杯子满了，
 * 任何溢出的香槟都会立刻等流量的流向左右两侧的玻璃杯。当左右
 * 两边的杯子也满了，就会等流量的流向它们左右两边的杯子，依次
 * 类推。（当最底层的玻璃杯满了，香槟会流到地板上）
 * 例如，在倾倒一杯香槟后，最顶层的玻璃杯满了。倾倒了两杯香槟后，
 * 第二层的两个玻璃杯各自盛放一半的香槟。在倒三杯香槟后，第二层的
 * 香槟满了 - 此时总共有三个满的玻璃杯。在倒第四杯后，第三层中间
 * 的玻璃杯盛放了一半的香槟，他两边的玻璃杯各自盛放了四分之一的香
 * 槟，如下图所示。
 * 现在当倾倒了非负整数杯香槟后，返回第 i 行 j 个玻璃杯所盛放的
 * 香槟占玻璃杯容积的比例（ i 和 j 都从0开始）。
 * <p>
 * 来源：力扣（LeetCode）
 * 链接：https://leetcode.cn/problems/champagne-tower
 */
public class 香槟塔_799 {

    public static void main(String[] args) {

        System.out.println(champagneTower(25, 6, 1));

    }

    /**
     * 模拟
     * 误区：并不是每一层必须等待上一层全部装满之后才开始装，因为中间的流速
     * 要快一些
     * 一层一层遍历，每一层都是由上一层的一个或者两个杯子-1 的一半，每一层
     * 假设可以装 > 1 个杯子的容量，相当于装满了，还能往下流动
     */
    public static double champagneTower(int poured, int query_row, int query_glass) {
        double[] container = new double[1];
        container[0] = poured;
        for (int row = 1; row <= query_row; row++) {
            double[] nextContainer = new double[row + 1];

            for (int i = 0; i < nextContainer.length; i++) {
                // 上一层装满了才往下层流动，> 1
                if (i < container.length && container[i] > 1) {
                    nextContainer[i] += (container[i] - 1) / 2D;
                }
                if (i - 1 >= 0 && container[i - 1] > 1) {
                    nextContainer[i] += (container[i - 1] - 1) / 2D;
                }
            }
            container = nextContainer;
        }

        return Math.min(1, container[query_glass]);
    }

}
